package com.alinesno.cloud.gateway.core.dispather;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.alinesno.cloud.gateway.core.annotation.SocketService;
import com.alinesno.cloud.gateway.core.context.ApplicationContextProvider;
import com.alinesno.cloud.gateway.core.dispather.factory.SocketServiceFactory;
import com.alinesno.cloud.gateway.core.dispather.socket.bean.BusinessServerBean;
import com.alinesno.cloud.gateway.core.dispather.socket.bean.RequestMessageBean;
import com.alinesno.cloud.gateway.core.dispather.socket.bean.ResponseMessageBean;
import com.alinesno.cloud.gateway.core.filter.FilterBean;
import com.alinesno.cloud.gateway.core.filter.FilterExecutionChain;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * Socket请求转发
 * 
 * @author LuoAnDong
 * @since 2019年9月21日 下午3:34:06
 */
@Scope("prototype") // 多例
@Component
@ChannelHandler.Sharable
public class SocketDispather extends ChannelInboundHandlerAdapter implements BaseDispather {

	private static final Logger log = LoggerFactory.getLogger(SocketDispather.class);

	private BusinessServerBean businessServerBean;

	@Autowired
	private FilterExecutionChain filterChain;

	/**
	 * 接口业务定位，按多级定位:<br/>
	 * [业务](业务代码) --> [接入方](银行代码) --> [接口标识](接口代码) --> [业务标识](交易码) <br/>
	 * 如: 消费贷接口(业务),接口代码(S45),交易码(412341231233)
	 */
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		log.debug("进入业务转发:{}", msg);

		InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();

		RequestMessageBean requestBean = (RequestMessageBean) msg;

		Map<String, Object> map = new HashMap<String, Object>();
		BeanUtils.populate(requestBean, map);
		FilterBean isNext = filterChain.doFilter(insocket, map);

		ResponseMessageBean response = null;
		if (isNext.isTag()) {

			String business = businessServerBean.getBusinessCode();
			String apiCode = requestBean.getApi();

			log.debug("业务:{} , 接口代码:{}", business, apiCode);

			SocketServiceFactory handler = querySocketService(businessServerBean, business, apiCode);
			response = handler.handle(requestBean, ctx);
		}

		ctx.write(response);
		ctx.flush();
	}

	private Map<String, Object> serviceMap = null;

	/**
	 * 获取到bean服务 
	 * @param businessServerBean
	 * @param business
	 * @param apiCode
	 * @return
	 */
	private SocketServiceFactory querySocketService(BusinessServerBean businessServerBean , String business, String apiCode) {
		if(serviceMap == null) { // 首次加载 
			serviceMap = ApplicationContextProvider.queryBeanWithAnno(SocketService.class) ;
		}
	
		SocketServiceFactory f = null ; 
	    for(Object obj : serviceMap.values()){
	    	SocketService s = obj.getClass().getAnnotation(SocketService.class) ; 
	    	if(s != null) {
	    		if(business.equals(s.busincess()) && apiCode.equals(s.api())) {
	    			f = (SocketServiceFactory) obj ; 
	    			break ; 
	    		}
	    	}
	    }
	
		return f ;
	}

	/**
	 * 读取完成
	 */
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
	}

	public BusinessServerBean getBusinessServerBean() {
		return businessServerBean;
	}

	public void setBusinessServerBean(BusinessServerBean businessServerBean) {
		this.businessServerBean = businessServerBean;
	}

}
